package com.googlecode.ipinfodb.client;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.StringTokenizer;

/**
 * @author Denis Migol
 * 
 */
public class IpInfoDbClient {

	public static final String API_CITY_URL = "http://api.ipinfodb.com/v3/ip-city/";
	public static final String API_COUNTRY_URL = "http://api.ipinfodb.com/v3/ip-country/";

	private final String apiUrl;
	private final String apiKey;
	private final WebClient webClient;

	public IpInfoDbClient(final String apiKey) {
		this(API_CITY_URL, apiKey, new WebClientImpl());
	}

	public IpInfoDbClient(final String apiUrl, final String apiKey) {
		this(apiUrl, apiKey, new WebClientImpl());
	}

	public IpInfoDbClient(final String apiKey, final WebClient webClient) {
		this(API_CITY_URL, apiKey, webClient);
	}

	public IpInfoDbClient(final String apiUrl, final String apiKey, final WebClient webClient) {
		this.apiUrl = apiUrl;
		this.apiKey = apiKey;
		this.webClient = webClient;
	}

	/**
	 * @return the apiKey
	 */
	public String getApiKey() {
		return apiKey;
	}

	protected String buildUrl(final String ip) {
		return apiUrl + "?" + new ParamsBuilder().setKey(apiKey).setIp(ip).build();
	}

	public String getInfo(final String ip) {
		try {
			return webClient.getContent(new URL(buildUrl(ip)));
		} catch (final MalformedURLException e) {
			return null;
		}
	}

	protected CityInfo parseCityInfo(final String s) {
		final CityInfo ret = new CityInfo();
		final StringTokenizer tokenizer = new StringTokenizer(s, ";");
		int index = 0;
		while (tokenizer.hasMoreElements()) {
			final String token = tokenizer.nextToken();
			index++;
			switch (index) {
			case 2: // ipAddress
				ret.setIpAddress(token);
				break;
			case 3: // countryCode
				ret.setCountryCode(token);
				break;
			case 4: // countryName
				ret.setCountryName(token);
				break;
			case 5: // regionName
				ret.setRegionName(token);
				break;
			case 6: // cityName
				ret.setCityName(token);
				break;
			case 7: // zipCode
				try {
					ret.setZipCode(Long.parseLong(token));
				} catch (final Exception e) {
				}
				break;
			case 8: // latitude
				try {
					ret.setLatitude(Float.parseFloat(token));
				} catch (final Exception e) {
				}
				break;
			case 9: // longitude
				try {
					ret.setLongitude(Float.parseFloat(token));
				} catch (final Exception e) {
				}
				break;
			case 10: // timeZone
				ret.setTimeZone(token);
				break;
			}
		}
		return ret;
	}

	public CityInfo getCityInfo(final String ip) {
		try {
			return parseCityInfo(webClient.getContent(new URL(buildUrl(ip))));
		} catch (final MalformedURLException e) {
			return null;
		}
	}
}
